package utiles
{
	import flash.display.DisplayObject;
	import flash.display.MovieClip;
	import flash.display.Sprite;
	import flash.events.MouseEvent;
	import flash.ui.Mouse;

	public class MouseCursorHelper
	{
		public function MouseCursorHelper()
		{
		}
		
		private static var _instance:MouseCursorHelper = null;
		public static function get instance():MouseCursorHelper {
			if (_instance == null)
				_instance = new MouseCursorHelper();
			return _instance;
		}
		
		
		private var _layer:Sprite;
		private var _currStyle:String;
		private var _styleToDisplayerObject:Object = {};
		
		public function registerStyle(style:String, skin:MovieClip):void
		{
			_styleToDisplayerObject[style] = skin;
			
			if (style == _currStyle)
				show(style);
		}
		
		public function unregisterStyle(style:String):void
		{
			_styleToDisplayerObject[style] = null;
			restore();
		}
		
		public function set layer(value:Sprite):void
		{
			if (value == _layer) {
				return;
			}
			
			var currCursorInstance:DisplayObject = _styleToDisplayerObject[_currStyle];
			if (currCursorInstance && _layer.contains(currCursorInstance)) {
				_layer.removeChild(currCursorInstance);
			}
			
			if (_layer && _layer.hasEventListener(MouseEvent.MOUSE_MOVE)) {
				_layer.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
			}
			
			_layer = value;
			if (_layer) {
				_layer.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
				
				if (currCursorInstance) {
					_layer.addChild(currCursorInstance);
				}
			}
		}
		
		public function get layer():Sprite
		{
			return _layer;
		}
		
		public function show(style:String):void
		{
			if (!_layer || !style) {
				restore();
				return;
			}
			
			if (style == _currStyle) {
				return;
			}
			
			var cursor:DisplayObject = _styleToDisplayerObject[style];
			if (!cursor) {
				restore();
				return;
			}
			
			var oldCursor:DisplayObject = _styleToDisplayerObject[_currStyle];
			if (oldCursor) {
				cursor.x = oldCursor.x;
				cursor.y = oldCursor.y;
				
				if (_layer.contains(oldCursor)) {
					_layer.removeChild(oldCursor);
				}
			}
			
			_currStyle = style;
			_layer.addChild(cursor);
			
			if (_layer && !_layer.hasEventListener(MouseEvent.MOUSE_MOVE)) {
				_layer.stage.addEventListener(MouseEvent.MOUSE_MOVE, onMove);
			}
		}
		
		public function restore():void
		{
			Mouse.show();
			
			var cursor:DisplayObject = _styleToDisplayerObject[_currStyle];
			if (cursor && _layer.contains(cursor)) {
				_layer.removeChild(cursor);
			}
			
			if (_layer) {
				_layer.stage.removeEventListener(MouseEvent.MOUSE_MOVE, onMove);
			}
			
			_currStyle = null;
		}
		
		private function onMove(event:MouseEvent):void
		{
			var currSkin:DisplayObject = _styleToDisplayerObject[_currStyle];
			if (currSkin && _layer)
			{
				currSkin.x = _layer.stage.mouseX;
				currSkin.y = _layer.stage.mouseY;
				Mouse.hide();
			}
		}
	}
}